﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using DocManagerORM.ORM;
using DocManagerControls.CLASSI;
using System.Diagnostics;
using DS2171Utils;
using DocManagerORM.Caching;

namespace DocManagerControls.Controls
{
    /// <summary>
    /// Logica di interazione per DocumentiControl.xaml
    /// </summary>
    public partial class DocumentiControl : BaseCusControl
    {


        Dictionary<int, string[]> m_dictSottoCat = new Dictionary<int, string[]>();
        Lazy<Encryptor> m_Encryptor = new Lazy<Encryptor>(() => { return new Encryptor(); });
        Lazy<ZipDati> m_ZipDati = new Lazy<ZipDati>(() => { return new ZipDati(); });
               
        QueryDoc m_QueryDoc = new QueryDoc();

        string _pwd = "diego1";


        // ******************************************

        public DocumentiControl()
        {
            InitializeComponent();

            CaricaDatiVari();
            this.txtNomeDoc.Focus();

            

            //addMenuHandler((e) => {

            //    switch (e)
            //    { 
            //        case "exit":
            //            MessageBox.Show("handler ok");  
            //            break;
            //    }

            //    ; }); 
        }

        private void CaricaDatiVari()
        {
            CacheBase.BindaComboBoxdata<Categorie>(ref comboCategorie, "Categorie", "ID", "Categoria");
            CacheBase.BindaComboBoxdata<Categorie>(ref comboCategorieRicerche, "Categorie", "ID", "Categoria");

            CacheBase.BindaComboBoxdata<SottoCategorie>(ref comboSottoCategorie, "SottoCategorie", "ID", "Categoria");
            CacheBase.BindaComboBoxdata<SottoCategorie>(ref comboSottoCategorieRicerche, "SottoCategorie", "ID", "Categoria");

            CacheBase.BindaComboBoxdata<aspnet_Roles>(ref comboRuoliModifica, "aspnet_Roles", "RoleID", "RoleName");
            CacheBase.BindaComboBoxdata<aspnet_Roles>(ref comboRuoliVisibilità, "aspnet_Roles", "RoleID", "RoleName");

            CacheBase.BindaComboBoxdata<Tags>(ref comboTagsPredefiniti, "Tags", "ID", "Tags1");
            CacheBase.BindaComboBoxdata<Tags>(ref comboTagsPredefinitiRicerche, "Tags", "ID", "Tags1");
            
        }//fM


        #region Caricamento

        private void txtDocPath_DragOver(object sender, DragEventArgs e)
        {
            bool isCorrect = true;

            if (e.Data.GetDataPresent(DataFormats.FileDrop, true) == true)
            {
                string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, true);
                foreach (string filename in filenames)
                {
                    txtDocPath.Text = filename;

                    if (File.Exists(filename) == false)
                    {
                        isCorrect = false;
                        break;
                    }
                    FileInfo info = new FileInfo(filename);
                    if (info.Extension != ".txt")
                    {
                        isCorrect = false;
                        break;
                    }
                }
            }
            if (isCorrect == true)
                e.Effects = DragDropEffects.All;
            else
                e.Effects = DragDropEffects.None;
            e.Handled = true;


        }

        private void txtDocPath_DragEnter(object sender, DragEventArgs e)
        {
            //MessageBox.Show("enter");
            txtDocPath.Text = " ... ";
        }

        private void txtDocPath_PreviewDragOver(object sender, DragEventArgs e)
        {

        }//fm

        private void txtDocPath_PreviewDragEnter(object sender, DragEventArgs e)
        {
            bool isCorrect = true;

            if (e.Data.GetDataPresent(DataFormats.FileDrop, true) == true)
            {
                string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, true);
                foreach (string filename in filenames)
                {
                    if (File.Exists(filename) == false)
                    {
                        isCorrect = false;
                        break;
                    }
                    FileInfo info = new FileInfo(filename);
                    if (info.Extension != ".txt")
                    {
                        isCorrect = false;
                        break;
                    }
                }
            }
            if (isCorrect == true)
                e.Effects = DragDropEffects.All;
            else
                e.Effects = DragDropEffects.None;
            e.Handled = true;

        }//fM
        
        private void btnCarica_Click(object sender, RoutedEventArgs e)
        {

            try
            {
                if (string.IsNullOrEmpty(txtDocPath.Text))
                {
                    lblMessaggi.Content = "Selezionare un file\\documento da salvare";
                    return;
                }

                if (!File.Exists(txtDocPath.Text))
                {
                    lblMessaggi.Content = "Percorso del file non trovato !";
                    return;
                }

                var cat = comboCategorie.SelectedItem as Categorie;
                if (cat == null)
                {
                    messaggia("Selezionare la categoria di appartenenza del documento...");
                    return;
                }


                var sottoCat = comboSottoCategorie.SelectedItem as SottoCategorie;
                if (sottoCat == null)
                {
                    messaggia("Selezionare la SottoCategoria di appartenenza del documento \\ documento...");
                    return;
                }

                byte[] arrBytes = null;
                var fileInfo = new FileInfo(txtDocPath.Text);

                //prelevo i dati in bytes
                arrBytes = m_ZipDati.Value.ReadFileFromPath(txtDocPath.Text);
                
                //m_ZipDati.Value.Test(arrBytes); 

                //cripta
                bool isEncrypted = false;
                if (checkCripta.IsChecked.Value)
                {
                    isEncrypted = true;
                    arrBytes = m_Encryptor.Value.Encrypt(arrBytes, _pwd);
                }


                int originalSize = arrBytes.Length;

                var isCompresso = checkComprimi.IsChecked.Value;
                bool compressInMemoria = true; // <<< OK in memory

                if (isCompresso)//compressione ?
                {
                    arrBytes = m_ZipDati.Value.CompressInMemory(arrBytes);
                    //using (var stream = fileZippato.OpenRead())
                    //{
                    //    long numBytes = stream.Length;
                    //    using (var br = new BinaryReader(stream))
                    //    {
                    //        arrBytes = br.ReadBytes((int)numBytes);
                    //    }
                    //}                
                }

                if (arrBytes == null) return;   // return se dati non validi

                var note = txtNote.Text;

                var filename = System.IO.Path.GetFileName(txtDocPath.Text);
                var estensione = System.IO.Path.GetExtension(txtDocPath.Text);

                int? idTagsPredefiniti = null;
                var tagsPred = comboTagsPredefiniti.SelectedItem as Tags;
                if (tagsPred != null) idTagsPredefiniti = tagsPred.ID; 


                string tagPersonali = txtTagsPersonalizzati.Text.Trim();


                //Guid guidRuoloVedi = default(Guid) ;
                var ruoloVedi = comboRuoliVisibilità.SelectedItem as aspnet_Roles;
                if (ruoloVedi == null)
                {
                    messaggia("Selezionare il ruolo di visibilità del documento \\ documento...");
                    return;
                }

                //Guid guidRuoloModifica = default(Guid);
                var ruoloMod = comboRuoliModifica.SelectedItem as aspnet_Roles;
                if (ruoloMod == null)
                {
                    messaggia("Selezionare il ruolo di modifica del documento \\ documento...");
                    return;
                }

                // >>> Salvataggio documento
                var affected = m_QueryDoc.salvaNuovoDocInDb(filename, arrBytes, estensione, cat.ID,
                    sottoCat.ID, idTagsPredefiniti, tagPersonali, ruoloVedi.RoleId, ruoloMod.RoleId, note,originalSize,
                    isCompresso, isEncrypted);

                lblMessaggi.Content = string.Format(" {0} documento salvato correttamente con id : {1}  [ {2}  ",
                    affected.Item1.ToString(), affected.Item2.ToString(), DateTime.Now.ToShortTimeString());

            }
            catch (Exception ex)
            {
                lblMessaggi.Content = "Errore, Documento non Caricato :\r\n" + ex.Message;
            }

        }
        
        private void Grid_PreviewDrop(object sender, DragEventArgs e)
        {
            PreviewDrag(e);
        }

        private void grid1_DragOver(object sender, DragEventArgs e)
        {

        }

        private void menu1_Click(object sender, RoutedEventArgs e)
        {
            MenuHandler(e);
        }//fm

        private void MenuHandler(RoutedEventArgs e)
        {
            m_Azione = ((MenuItem)e.OriginalSource).Header.ToString().ToLower();

            switch (m_Azione)
            {
                case "exit":
                    this.Visibility = System.Windows.Visibility.Hidden;
                    break;
                case "carica":

                    break;
                default:
                    break;
            }
        }

        private void comboCategorie_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var cat = comboCategorie.SelectedItem as Categorie;
            if (cat == null) return;

            CacheBase.BindaComboBoxdata<SottoCategorie>(ref comboSottoCategorie, "SottoCategorie", "ID",
                "Categoria", cat.ID);

            //comboSottoCategorie.ItemsSource = m_LookUpSottoCat[cat.ID];

        }//fM

        private void PreviewDrag(DragEventArgs e)
        {
            string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, true);
            Controls.ViewBox vbb = null;
            string ext = "";

            foreach (string filename in filenames)
            {
                txtDocPath.Text = filename;

                ext = System.IO.Path.GetExtension(filename);

                if (this.checkBoxVedi.IsChecked.Value)
                {
                    vbb = new ViewBox();
                    if (ext == ".pdf") showPDF(filename);

                    if (ext == ".txt")
                    {
                        vbb.Messaggio = File.ReadAllText(filename);
                        txtDocPath.Text = filename;
                        vbb.ShowDialog();
                    }
                }
            }

            e.Handled = true;
        }//fM


        #endregion

         // ****************************
        //*******************************

        #region Ricerche

        
        private void showPDF(string pFile)
        {
            Process process = new Process();
            process.StartInfo.Verb = "Open"; //"PrintTo";

            process.StartInfo.FileName = @"C:\Program Files\Adobe\Reader 9.0\Reader\acrord32.exe";

            process.StartInfo.Arguments = string.Format(" \"{0}\" ", pFile); //   /t

            process.StartInfo.RedirectStandardOutput = false;
            process.StartInfo.CreateNoWindow = true;

            process.StartInfo.UseShellExecute = false;

            process.Start();

            //process.StandardOutput.ReadToEnd();

            process.WaitForExit();

        }//fm


        protected void btnCerca_Click(object sender, RoutedEventArgs e)
        {
            CercaDoc();

        }//fm

        private void CercaDoc()
        {
            string docName = string.Empty;
            int catID , sottoCatID , tagsID;
            int? catIDnull=null , sottoCatIDnull=null, tagsIDnull=null;
            
            try
            {

                if (!string.IsNullOrEmpty(txtNomeDoc.Text))
                {
                    docName = txtNomeDoc.Text;
                }
                else
                {
                    if (this.comboCategorieRicerche .SelectedValue != null)
                    {
                        int.TryParse(comboCategorieRicerche.SelectedValue.ToString(), out catID);
                        catIDnull = catID ;
                    }
                    
                    if (this.comboSottoCategorieRicerche.SelectedValue != null)
                    {
                        int.TryParse(comboSottoCategorieRicerche.SelectedValue.ToString(), out sottoCatID);
                        sottoCatIDnull = sottoCatID ;
                    }
                }

                if (this.comboTagsPredefinitiRicerche.SelectedValue != null)
                    {
                        int.TryParse(comboTagsPredefinitiRicerche.SelectedValue.ToString(), out tagsID);
                        tagsIDnull = tagsID;
                    }                 

                var tagsPersonali = this.txtTagsPersonalizzatiRicerche.Text.Trim();   

                //Preleva la VISTA dei documenti <<<<<<<<<<
                var arrDocs = new QueryDoc().prelevaDocView(docName,checkBoxIsID.IsChecked.Value, catIDnull, sottoCatIDnull,
                   tagsIDnull,tagsPersonali ).ToArray();

                listDocs.ItemsSource = arrDocs;

                var totDocs = 0;
                totDocs = arrDocs == null ? 0 : arrDocs.Length;

                lblMessaggi.Content = string.Format("{0} documenti prelevati ( {1}", totDocs, DateTime.Now.ToLongTimeString());

            }
            catch (Exception ex)
            {
                lblMessaggi.Content = "Errore : Documento non modificato ( " + ex.Message;
            }
        }


        private void comboCategorieRicerche_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var combo = sender as ComboBox;
            var cat = combo.SelectedItem as Categorie;
            if (cat == null) return;

            CacheBase.BindaComboBoxdata<SottoCategorie>(ref comboSottoCategorieRicerche, "SottoCategorie", "ID",
                "Categoria", cat.ID);  
        }


        private void listDocs_Selected(object sender, RoutedEventArgs e)
        {
            
        }//fM
               

        private void listDocs_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = e.OriginalSource as Image;
            if (item == null) return;

            int idDoc = 0;
            if (!int.TryParse(item.Tag.ToString(), out idDoc)) return;

            var doc = m_QueryDoc.prelevaDoc(idDoc).FirstOrDefault();
            var dir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Documenti");
            
            if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
            var filePath = System.IO.Path.Combine(dir, doc.FileName);

            DocUtils.SaveBytesInFile(filePath, doc.Documento);
            DocUtils.showDoc(filePath);

        }

        private void txtNomeDoc_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers != ModifierKeys.Shift)
            {
                CercaDoc();
                e.Handled = true;
            }
        }//fM

        private void contMenu_Click(object sender, RoutedEventArgs e)
        {
            var lst =contMenu.PlacementTarget as ListView;
            var selDoc = lst.SelectedItem as vwDocumenti;//documento
            if (selDoc == null) return;

            var comando = ((MenuItem)e.Source).Header.ToString().ToLower();
            switch (comando)
            {
                case "vedi":
                    vediDocumento(selDoc);
                    break;
                case "read":

                    break;
                case "modifica":

                    break;
                case "download":

                    break;
                case "delete":

                    break;
                case "avvia iter":
                    CreaWFControl iter = new CreaWFControl(selDoc.ID,selDoc.FileName);
                    getFrameContainer().Content = iter;
                    break;
                default:
                    break;
            }

        }

        private void vediDocumento(vwDocumenti selDoc)
        {
            prelevaDoc(selDoc);          
        }
        

        private void btnVediDoc_Click(object sender, RoutedEventArgs e)
        {

        }//fM

        //preleva ed eventualmente decomprime il documento
        public void prelevaDoc(vwDocumenti pSelDoc)
        {
            var doc = m_QueryDoc.prelevaDoc(pSelDoc.ID).FirstOrDefault();

            var tempDir = System.IO.Path.Combine(Environment.CurrentDirectory,"TempFiles",doc.FileName);

            byte[] arrBytes = doc.Documento;

            int lunghezzaOriginaria = doc.OriginalSize.Value ;

            if (doc.IsZipped.GetValueOrDefault() || doc.FileName.Contains(".gz"))
            {
                var path = System.IO.Path.Combine(Environment.CurrentDirectory, "TempFiles", pSelDoc.FileName);

                arrBytes = m_ZipDati.Value.Decompress(arrBytes, lunghezzaOriginaria);
            }


            var isEncrypted = true;
            if (isEncrypted)
            {
                arrBytes = m_Encryptor.Value.Decrypt(arrBytes, _pwd);

                var sampleOut = new System.Text.ASCIIEncoding().GetString(arrBytes.ToArray());
                
                using (var stream = File.Create(tempDir))
                {                    
                    stream.Write(arrBytes, 0, arrBytes.Length);
                    stream.Flush(true);
                }

            }
            else
                arrBytes = doc.Documento;
         
        }

        #endregion


        // *******************************
        // *******************************

    }//fC
}
